'\"macro stdmacro
.\"
.\" Copyright (c) 2016-2017 Red Hat.
.\"
.\" This program is free software; you can redistribute it and/or modify it
.\" under the terms of the GNU General Public License as published by the
.\" Free Software Foundation; either version 2 of the License, or (at your
.\" option) any later version.
.\"
.\" This program is distributed in the hope that it will be useful, but
.\" WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
.\" or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
.\" for more details.
.\"
.\"
.TH PMJSONGET 3 "PCP" "Performance Co-Pilot"
.SH NAME
\f3pmjsonGet\f1,
\f3pmjsonPrint\f1,
\f3pmjsonInit\f1,
\f3pmjsonInitIndom\f1 \- JSON string helpers and metrics extraction
.SH "C SYNOPSIS"
.ft 3
.ad l
.hy 0
#include <pcp/pmapi.h>
.br
#include <pcp/pmjson.h>
.sp
typedef int (*json_get)(void *\fIbuffer\fP,
'in +\w'typedef int ('u
int\ \fIlength\fP,
void\ *\fIdata\fP);
.in
.br
int pmjsonGet(json_metric_desc *\fIjson_metrics\fP,
'in +\w'int pmjsonGet('u
int\ \fInmetrics\fP,
pmInDom\ \fIindom\fP,
json_get\ \fIcallback\fP,
void\ *\fIdata\fP);
.in
.br
int pmjsonPrint(FILE *\fIfp\fP,
'in +\w'int pmjsonPrint('u
json_flag\ *\fIoutput_flags\fP,
const\ char\ *\fIjson_pointer\fP,
json_get\ \fIcallback\fP,
void\ *\fIdata\fP);
.in
.sp
int pmjsonInit(int \fIfd\fP,
'in +\w'int pmjsonInit('u
json_metric_desc\ *\fIjson_metrics\fP,
int\ \fInmetrics\fP);
.in
.br
int pmjsonInitIndom(int \fIfd\fP,
'in +\w'int pmjsonInitIndom('u
json_metric_desc\ *\fIjson_metrics\fP,
int\ \fInmetrics\fP,
pmInDom\ \fIindom\fP);
.in
.sp
cc ... \-lpcp_web
.hy
.ad
.ft 1
.SH DESCRIPTION
\f3pmjsonGet\f1 performs metric value extraction from JSON strings for a
Performance Metric Domain Agent (\fBPMDA\fP(3)).
Metrics and instances are defined by the \f2json_metrics\f1 parameter.
The result of parsing is the extraction of values for the requested
metrics (as defined in the
.I json_pointer
field) in the values field.
.PP
A simple diagnostic utility for reporting JSON strings is provided as
a convenience as well.
Its
.I output_flags
argument allows it to support a variety of alternate output formats,
including minimal JSON (no optional whitespace), pretty-printed, and
a simple YAML subset.
.PP
\f2json_metrics\f1 is the array of json_metric_desc struct which
contains the json pointer to the metric data, possible flags to check
the data against, number of values (in the case of an array),
\f2pmAtomValue\f1 where the data is stored, as well as the instance
domain in the event the PMDA has multiple instance domains.
The number of elements in the
.IR json_metrics
array is indicated by the \f2nmetrics\f1 parameter.
.PP
Interfaces for common cases are provided \- \f3pmjsonInit\f1 specifies
a call to the JSON parsing and metric value extraction functionality
where there are no instance domains (or the PMDA wishes to perform
instance domain operations itself) and where data can be read directly
from an open file descriptor.
\f3pmjsonInitIndom\f1 is similar, but makes use of the
.BR pmdaCacheStore (3)
function where possible.
.PP
The JSON string must be provided by the \f2callback\f1 function.
This function is passed a memory \f2buffer\f1 of \f2length\f1 bytes and
an opaque user \f2data\f1 pointer which is unchanged from the original
call to
.BR pmjsonGet
or
.BR pmjsonPrint .
The returned result must be the number of bytes written into \f2buffer\f1,
zero when no more data is available or less than zero on error conditions.
.PP
\f2indom\f1 is the instance domain to be passed to \f3pmdaCacheStore\f1.
.P
.nf
	typedef struct json_metrics_desc {
	    char          *json_pointer;  /* json pointer to metric */
	    int           flags;          /* flags to check if set */
	    int           num_values;     /* number of values */
	    pmAtomValue   values;         /* metric value */
	    char          *dom;           /* instance domain */
	} json_metric_desc;
.fi
.P
The JSON Pointer syntax current follows \f2RFC6901\f1 in specifying a
metrics location within the JSON document.
.SH EXAMPLE
For the sample JSON document:
.P
.ft CR
.nf
{
    "Name": "/clever_almeida",
    "State": {
        "Dead": false,
        "Error": "",
        "ExitCode": 0,
        "FinishedAt": "2016-07-18T21:21:20.332488706Z",
        "OOMKilled": false,
        "Paused": false,
        "Pid": 0,
        "Restarting": false,
        "Running": false,
        "StartedAt": "2016-07-18T14:10:58.52487316Z"
    }
}
.fi
.ft R
.P
A possible corresponding json_metric array would be as follows for the
Pid, Name, and metrics to indicate whether the container is Running,
Paused, or Restarting.
.P
.ft CR
.nf
static json_metric_desc json_metrics[] = {
    { "State/Pid", 0, 1, {0}, ""},
    { "Name", 0, 1, {0}, ""},
    { "State/Running", CONTAINER_FLAG_RUNNING, 1, {0}, ""},
    { "State/Paused", CONTAINER_FLAG_PAUSED, 1, {0}, ""},
    { "State/Restarting", CONTAINER_FLAG_RESTARTING, 1, {0}, ""},
};
.fi
.ft R
.SH RETURN CODE
The functions return zero on success, otherwise an error code suitable
for passing to
.BR pmErrStr_r (3)
is returned.
.SH SEE ALSO
.BR PMDA (3),
.BR pmErrStr_r (3),
.BR pmdaCacheStore (3),
.nh
.BR https://www.json.org/ ,
.hy
.nh
.BR https://tools.ietf.org/html/rfc7159 ,
.hy
and
.nh
.BR https://tools.ietf.org/html/rfc6901 .
.hy

.\" control lines for scripts/man-spell
.\" +ok+ CONTAINER_FLAG_RESTARTING CONTAINER_FLAG_RUNNING CONTAINER_FLAG_PAUSED
.\" +ok+ json_metrics_desc clever_almeida
.\" +ok+ json_metric FinishedAt num_values OOMKilled json_flag StartedAt
.\" +ok+ json_get ExitCode YAML ietf rfc Pid
.\" +ok+ dom {C variable}
